﻿using System;
using System.Linq;
using System.Web.Http;
using Newtonsoft.Json;
using System.Threading;
using System.Web.Configuration;
using log4net;
using AlipaySDK.Dto.Payment;
using AlipaySDK.Helper;
using In.Api.Dto.Notify;
using In.Api.Dto.Notify.Notification;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Dto.QrCode;
using User.Api.Helpers;

namespace User.Api.Controllers
{
    public class ApiNotifyController : ApiController
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(ApiNotifyController));
        [AllowAnonymous]
        [HttpPost]
        public NotificationResponse Notification(NotificationRequest notification)
        {
            string resultDesc = string.Empty;
            switch (notification.NotificationType)
            {
                case  "CommonNotice":
                    CommonNotice(notification);
                    break;
                case "HaltNotice":
                    if (!HaltNotice(notification))
                    {
                        return new NotificationResponse() { ResultCode = "1", ResultDesc = "" };
                    }
                    break;
                case "RefundNotice":
                    RefundNotice(notification);
                    break;
                case "CreateQRCode":
                {
                    var responseStr=CreateQRCodeNotice(notification,ref resultDesc);
                    if (responseStr!="")
                      return new NotificationResponse() { ResultCode = "0", ResultDesc = "", ResponseInfo = responseStr };
                    else
                    {
                        return new NotificationResponse() { ResultCode = "1", ResultDesc = resultDesc, ResponseInfo = responseStr };
                    }
                }
                case "BarcodePayOffline":
                {
                    var responseStr = BarcodePayOfflineNotice(notification,ref resultDesc);
                    if (responseStr != "")
                        return new NotificationResponse() { ResultCode = "0", ResultDesc = "", ResponseInfo = responseStr };
                    else
                    {
                        return new NotificationResponse() { ResultCode = "1", ResultDesc = resultDesc, ResponseInfo = responseStr };
                    }
                }
                case "QueryOrderStatus":
                {
                    var responseStr = GetBillStatus(notification);
                    return new NotificationResponse() { ResultCode = "0", ResultDesc = "", ResponseInfo = responseStr };
                }
                //case "PrepayBarcodePayOfflineNotice":
                //{
                //    var responseStr = PrepayBarcodePayOfflineNotice(notification,ref resultDesc);
                //    if (responseStr != "")
                //        return new NotificationResponse() { ResultCode = "0", ResultDesc = "", ResponseInfo = responseStr };
                //    else
                //    {
                //        return new NotificationResponse() { ResultCode = "1", ResultDesc = resultDesc, ResponseInfo = responseStr };
                //    }
                //}
                //case "InpatientNotice":
                //    InpatientNotice(notification);
                //    break;
                //case "InpatientBillNotice":
                //    InpatientBillNotice(notification);
                //    break;
            }
            return new NotificationResponse() {ResultCode = "0", ResultDesc = ""};
        }

        private string BarcodePayOfflineNotice(NotificationRequest notification,ref string resultDesc)
        {
            string responseInfo = "";
            var notificationInfo = JsonConvert.DeserializeObject<QRInfo>(notification.NotificationInfo);
            
            try
            {
                var insertLocalOrder = true;
                var newOrderNo = BillController.GenerateNewOrderNo();
                using (var ctx = new GdsfybjyWeiXinEntities())
                {
                        try
                        {
                            var unPayStatus = BillOrderExtensions.OrderStatus.未支付.ToInt32();
                            var order = ctx.BillOrders.FirstOrDefault(x => x.CardType == notificationInfo.CardType && x.CardNo == notificationInfo.CardNo
                                && x.ClinicNo == notificationInfo.ClinicNo && x.OrderDate == notificationInfo.OrderDate
                                && (x.OrderStatus == unPayStatus) && x.AliPayType== "BARCODEPAYOFFLINE");
                            if (order != null && order.PrescMoney == notificationInfo.PrescMoney)
                            {
                                newOrderNo = order.OrderNo;
                            }
                            else
                            {
                                var newBillOrder = new BillOrder
                                {
                                    Remark = notificationInfo.Remark,
                                    CardNo = notificationInfo.CardNo,
                                    CardType = notificationInfo.CardType,
                                    ClinicNo = notificationInfo.ClinicNo,
                                    OrderNo = newOrderNo,
                                    OrderDate = notificationInfo.OrderDate,
                                    OrderDept = notificationInfo.OrderDept,
                                    PrescMoney = notificationInfo.PrescMoney,
                                    CreateTime = DateTime.Now,
                                    YiBaoStatus = notificationInfo.YiBaoStatus.ToInt32OrDefault(),
                                    YiBaoIndiId = notificationInfo.YiBaoIndiId,
                                    YiBaoJydjh = notificationInfo.YiBaoJydjh,
                                    YibaoMoney = notificationInfo.YibaoMoney,
                                    PersonalMoney = notificationInfo.PersonalMoney,
                                    AliPayType = "BARCODEPAYOFFLINE",
                                    OrderStatus = BillOrderExtensions.OrderStatus.未支付.ToInt32(), 
                                    PayState = BillOrderExtensions.PayState.未付款.ToInt32().ToString() 
                                };
                                ctx.BillOrders.Add(newBillOrder);
                                ctx.SaveChanges();

                                if (notificationInfo.BillOrderItem != null)
                                {
                                    foreach (QRInfo.OrderItem item in notificationInfo.BillOrderItem)
                                    {
                                        ctx.BillOrderItems.Add(new BillOrderItem
                                        {
                                            BillOrderId = newBillOrder.Id,
                                            ItemPrice = item.price,
                                            Unit = item.unit,
                                            Name = item.goodsName,
                                            Account = item.quantity.ToStringOrDefault(),
                                            Type = item.type,
                                            Money = item.price.ToDecimalOrDefault()*item.quantity.ToDecimalOrDefault()
                                        });
                                    }
                                }

                                ctx.SaveChanges();

                                // RMQ 16分钟后如果还是支付中则设置支付失败
                                var payingTimeoutProducer = new OrderPayingTimeoutProducer();
                                payingTimeoutProducer.Publish(new OrderPayingTimeoutMsg
                                {
                                    OrderType = OrderType.门诊缴费订单,
                                    OrderId = newBillOrder.Id
                                }, 16*60*1000);
                            }
      
                        }
                        catch (Exception ex)
                        {
                            insertLocalOrder = false;
                            Logger.ErrorFormat("调用BarcodePayOfflineNotice插入缴费订单及明细时出错，信息:{0}", JsonConvert.SerializeObject(ex));
                        }
                }
                if(insertLocalOrder)
                { 
                    var payFee = notificationInfo.PrescMoney.ToString();

                    PrecreatePayment payment = new PrecreatePayment();
                    var result = payment.FaceToFacePay(new CreateFacetoFacePaymentRequest
                    {
                        NotifyUrl = WebConfigurationManager.AppSettings["AlipayNotify"]+ "Bill/AlipayNotify",
                        OutTradeNo = notificationInfo.BillType + newOrderNo,
                        Subject = notificationInfo.BillType == "BL" ? "就诊缴费" : "预交金缴费",
                        TotalFee = payFee,
                        DynamicId = notificationInfo.DynamicId
                    });

                    if (result != null && result.ResultCode == "0")
                    {
                        responseInfo = newOrderNo;

                        //支付成功
                        if (result.TradeStatus == "10000")
                        {
                            //记录缴费成功通知
                            SavePayNotifyLog(result.TradeStatus, result.OutTradeNo, result.GmtPayment, result.TradeNo, result.OpenId, notificationInfo.PrescMoney.ToDecimalOrDefault());
                            new Thread(() =>
                                {
                                    ProccessFaceToFacePaidOrder(result.OutTradeNo, result.GmtPayment, result.TradeNo, result.OpenId, notificationInfo.PrescMoney.ToDecimalOrDefault());
                                }).Start();
                        }
                        else if (!string.IsNullOrEmpty(result.OutTradeNo))
                        {
                            new Thread(() =>
                            {
                                int retryCount = 0;
                                //更新订单状态
                                for (int i = 1; i <= 6; i++)
                                {
                                    Thread.Sleep(5000);

                                    var queryResult = payment.AcquireQuery(new WapPayQueryRequest
                                    {
                                        OutTradeNo = result.OutTradeNo
                                    });

                                    if (queryResult.ResultCode == "0")
                                    {
                                        if (queryResult.TradeStatu == "TRADE_FINISHED" ||
                                            queryResult.TradeStatu == "TRADE_SUCCESS")
                                        {
                                            ProccessFaceToFacePaidOrder(result.OutTradeNo, queryResult.GmtPayment,
                                                queryResult.TradeNo,
                                                queryResult.OpenId, notificationInfo.PrescMoney.ToDecimalOrDefault());
                                            break;
                                        }
                                        retryCount++;
                                    }
                                }
                                if (retryCount == 6)
                                {

                                    var cancelResult = payment.Cancel(new WapPayQueryRequest
                                            {
                                                OutTradeNo = result.OutTradeNo
                                            });

                                    //订单取消，支付异常，OrderStatus：3
                                    using (var ctx = new GdsfybjyWeiXinEntities())
                                    {
                                        var order = ctx.BillOrders.FirstOrDefault(x => x.OrderNo == newOrderNo);

                                        if (order != null)
                                        {
                                            order.OrderStatus = BillOrderExtensions.OrderStatus.支付失败.ToInt32();
                                            order.NextCheckTime = null;
                                            order.OrderStatusOnSetCheck = null;
                                            ctx.SaveChanges();
                                        }
                                    }
                                }
                            }).Start();
                        }
                        else
                        {
                            responseInfo = "";
                            resultDesc = "error";
                        }
                    }
                }
                else
                {
                    responseInfo = "";
                    resultDesc = "error";
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用BarcodePayOfflineNotice 调用Alipay SDK缴费时出错，信息:{0}", JsonConvert.SerializeObject(ex));
            }
            return responseInfo;
        }
        private string CreateQRCodeNotice(NotificationRequest notification, ref string resultDesc)
        {
            string responseInfo = "";
            var notificationInfo = JsonConvert.DeserializeObject<QRInfo>(notification.NotificationInfo);
            var newOrderNo = BillController.GenerateNewOrderNo();
            try
            {
                var payFee = notificationInfo.PrescMoney.ToString();
                var insertLocalOrder = true;
                using (var ctx = new GdsfybjyWeiXinEntities())
                {
                        try
                        {
                            var unPayStatus = BillOrderExtensions.OrderStatus.未支付.ToInt32();
                            var order = ctx.BillOrders.FirstOrDefault(x => x.CardType == notificationInfo.CardType && x.CardNo == notificationInfo.CardNo
                               && x.ClinicNo == notificationInfo.ClinicNo && x.OrderDate == notificationInfo.OrderDate
                               && x.OrderStatus == unPayStatus && x.AliPayType== "QRCODEOFFLINE");
                            if (order != null && order.PrescMoney == notificationInfo.PrescMoney)
                            {
                                newOrderNo = order.OrderNo;
                            }
                            else
                            {
                                var newBillOrder = new BillOrder
                                {
                                    Remark = notificationInfo.Remark,
                                    CardNo = notificationInfo.CardNo,
                                    CardType = notificationInfo.CardType,
                                    ClinicNo = notificationInfo.ClinicNo,
                                    OrderNo = newOrderNo,
                                    OrderDate = notificationInfo.OrderDate,
                                    OrderDept = notificationInfo.OrderDept,
                                    PrescMoney = notificationInfo.PrescMoney,
                                    CreateTime = DateTime.Now,
                                    YiBaoStatus = notificationInfo.YiBaoStatus.ToInt32OrDefault(),
                                    YiBaoIndiId = notificationInfo.YiBaoIndiId,
                                    YiBaoJydjh = notificationInfo.YiBaoJydjh,
                                    YibaoMoney = notificationInfo.YibaoMoney,
                                    PersonalMoney = notificationInfo.PersonalMoney,
                                    AliPayType = "QRCODEOFFLINE",
                                    OrderStatus = BillOrderExtensions.OrderStatus.未支付.ToInt32(),
                                    PayState = BillOrderExtensions.PayState.未付款.ToInt32().ToString()
                                };
                                ctx.BillOrders.Add(newBillOrder);
                                ctx.SaveChanges();

                                if (notificationInfo.BillOrderItem != null)
                                {
                                    foreach (QRInfo.OrderItem item in notificationInfo.BillOrderItem)
                                    {
                                        ctx.BillOrderItems.Add(new BillOrderItem
                                        {
                                            BillOrderId = newBillOrder.Id,
                                            ItemPrice = item.price,
                                            Unit = item.unit,
                                            Name = item.goodsName,
                                            Account = item.quantity.ToStringOrDefault(),
                                            Type = item.type,
                                            Money = item.price.ToDecimalOrDefault()*item.quantity.ToDecimalOrDefault()
                                        });
                                    }
                                }
                                ctx.SaveChanges();

                                // RMQ 16分钟后如果还是支付中则设置支付失败
                                var payingTimeoutProducer = new OrderPayingTimeoutProducer();
                                payingTimeoutProducer.Publish(new OrderPayingTimeoutMsg
                                {
                                    OrderType = OrderType.门诊缴费订单,
                                    OrderId = newBillOrder.Id
                                }, 16*60*1000);
                            }
                        }
                        catch (Exception ex)
                        {
                            insertLocalOrder = false;
                            Logger.ErrorFormat("调用CreateQRCodeNotice保存缴费单及明细时出错，信息:{0}", JsonConvert.SerializeObject(ex));
                        }
                }

                if (insertLocalOrder)
                {
                    QrCodePayment payment = new QrCodePayment();
                    var result = payment.CreateQrCodeResult(new ComposeWapPayRequest
                     {
                         NotifyUrl = WebConfigurationManager.AppSettings["AlipayNotify"] + "Bill/AlipayNotify",
                         OutTradeNo = notificationInfo.BillType + newOrderNo,
                         Subject = notificationInfo.BillType == "BL" ? "就诊缴费" : "预交金缴费",
                         TotalFee = payFee
                     });

                    if (result != null && result.ResultCode == "0")
                    {
                        responseInfo = result.CodeImg;
                    }
                    else
                    {
                        responseInfo = "";
                        resultDesc = "error";
                    }
                }
                else
                {
                    responseInfo = "";
                    resultDesc = "error";
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用Alipay CreateQRCode SDK 时出错，信息:{0}", JsonConvert.SerializeObject(ex));
            }
            return responseInfo;
        }

        //private string PrepayBarcodePayOfflineNotice(NotificationRequest notification, ref string resultDesc)
        //{
        //    string responseInfo = "";
        //    var notificationInfo = JsonConvert.DeserializeObject<PrePayInfo>(notification.NotificationInfo);
        //    var newOrderNo = InpatientController.GenerateNewOrderNo();
        //    try
        //    {
        //        using (var ctx = new GdsfybjyWeiXinEntities())
        //        {
        //            var unPayStatus = PrepayOrderExtensions.OrderStatus.未支付.ToInt32();
        //            var order =
        //                ctx.InpatientPrepayOrders.FirstOrDefault(
        //                    x => x.CardType == notificationInfo.CardType && x.CardNo == notificationInfo.CardNo
        //                         && x.OrderDate == notificationInfo.OrderDate
        //                         && x.OrderStatus == unPayStatus && x.AliPayType== "BARCODEPAYOFFLINE");
        //            if (order != null && order.PrepayMoney == notificationInfo.PrepayMoney)
        //            {
        //                    newOrderNo = order.OrderNo;
        //            }
        //            else
        //            {
        //                var newPrePayOrder = new InpatientPrepayOrder
        //                {
        //                    OpenId = "",
        //                    Remark = notificationInfo.Remark,
        //                    CardNo = notificationInfo.CardNo,
        //                    CardType = notificationInfo.CardType,
        //                    PatientId = notificationInfo.PatientId,
        //                    OrderNo = newOrderNo,
        //                    OrderDate = notificationInfo.OrderDate,
        //                    OrderDept = notificationInfo.OrderDept,
        //                    PrepayMoney = notificationInfo.PrepayMoney,
        //                    CreateTime = DateTime.Now,
        //                    VisitId = notificationInfo.VisitId,
        //                    InpatientId = notificationInfo.InpatientId,
        //                    AliPayType = "BARCODEPAYOFFLINE",
        //                    OrderStatus = PrepayOrderExtensions.OrderStatus.未支付.ToInt32(), 
        //                    PayState = PrepayOrderExtensions.PayState.未付款.ToInt32().ToString() 
        //                };
        //                ctx.InpatientPrepayOrders.Add(newPrePayOrder);
        //                ctx.SaveChanges();

        //                // RMQ 16分钟后如果还是支付中则设置支付失败
        //                var payingTimeoutProducer = new OrderPayingTimeoutProducer();
        //                payingTimeoutProducer.Publish(new OrderPayingTimeoutMsg
        //                {
        //                    OrderType = OrderType.住院预缴金订单,
        //                    OrderId = newPrePayOrder.Id
        //                }, 16 * 60 * 1000);
        //            }
        //        }

        //        PrecreatePayment payment = new PrecreatePayment();
        //        var payFee = notificationInfo.PrepayMoney.ToString();
        //        var result = payment.FaceToFacePay(new CreateFacetoFacePaymentRequest
        //        {
        //            NotifyUrl = WebConfigurationManager.AppSettings["AlipayNotify"] + "Bill/AlipayNotify",
        //            OutTradeNo = notificationInfo.BillType + newOrderNo,
        //            Subject = notificationInfo.BillType == "BL" ? "就诊缴费" : "预交金缴费",
        //            TotalFee = payFee,
        //            DynamicId = notificationInfo.DynamicId
        //        });
        //        if (result != null && result.ResultCode == "0")
        //        {
        //            responseInfo = newOrderNo;

        //            //支付成功
        //            if (result.TradeStatus == "10000")
        //            {
        //                //记录缴费成功通知
        //                SavePayNotifyLog(result.TradeStatus, result.OutTradeNo, result.GmtPayment,
        //                    result.TradeNo, result.OpenId, notificationInfo.PrepayMoney.ToDecimalOrDefault());

        //                new Thread(() =>
        //                {
        //                    ProccessFaceToFacePaidOrder(result.OutTradeNo, result.GmtPayment,
        //                        result.TradeNo, result.OpenId, notificationInfo.PrepayMoney.ToDecimalOrDefault());
        //                }).Start();
        //            }
        //            else if (!string.IsNullOrEmpty(result.OutTradeNo))
        //            {
        //                new Thread(() =>
        //                {
        //                    int retryCount = 0;
        //                    //更新订单状态
        //                    for (int i = 1; i <= 6; i++)
        //                    {
        //                        Thread.Sleep(5000);
        //                        var queryResult = payment.AcquireQuery(new WapPayQueryRequest
        //                                {
        //                                    OutTradeNo = result.OutTradeNo
        //                                });

        //                        if (queryResult.ResultCode == "0")
        //                        {
        //                            if (queryResult.TradeStatu == "TRADE_FINISHED" ||
        //                                queryResult.TradeStatu == "TRADE_SUCCESS")
        //                            {
        //                                ProccessFaceToFacePaidOrder( result.OutTradeNo,
        //                                    queryResult.GmtPayment, queryResult.TradeNo,
        //                                    queryResult.OpenId, notificationInfo.PrepayMoney.ToDecimalOrDefault());
        //                                break;

        //                            }
        //                        }
        //                        retryCount++;
        //                    }
        //                    if (retryCount == 6)
        //                    {
        //                        var cancelResult = payment.Cancel(new WapPayQueryRequest
        //                        {
        //                            OutTradeNo = result.OutTradeNo
        //                        });

        //                        //订单取消，支付异常，OrderStatus：3
        //                        using (var ctx = new GdsfybjyWeiXinEntities())
        //                        {
        //                            var order = ctx.InpatientPrepayOrders.FirstOrDefault(x => x.OrderNo == newOrderNo);

        //                            if (order != null)
        //                            {
        //                                order.OrderStatus = PrepayOrderExtensions.OrderStatus.支付失败.ToInt32();
        //                                order.NextCheckTime = null;
        //                                order.OrderStatusOnSetCheck = null;
        //                                ctx.SaveChanges();
        //                            }
        //                        }
        //                    }

        //                }).Start();
        //            }
        //        }
        //        else
        //        {
        //            responseInfo = "";
        //            resultDesc = "error";
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorFormat("调用PrepayBarcodeOffline时出错，信息:{0}", JsonConvert.SerializeObject(ex));
        //    }
        //    return responseInfo;
        //}



        private string GetBillStatus(NotificationRequest notification)
        {
            string responseInfo = "";
            var notificationInfo = JsonConvert.DeserializeObject<QueryOrderRequest>(notification.NotificationInfo);

            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                if (notificationInfo.BillOrderType == "BL")
                {
                    //支付状态：0未支付 1支付中 2支付成功 3支付失败 4退款中 5退款成功 6退款失败 7缴费中 8缴费成功 9缴费失败 10窗口退款成功
                    var order = ctx.BillOrders.FirstOrDefault(x => x.OrderNo == notificationInfo.BillOrderNo);
                    if (order != null) responseInfo = order.OrderStatus.ToString();
                    //缴费中则重新支付，会有冲突
                    //if (responseInfo == "7")
                    //{
                    //    new Thread(() =>
                    //        {
                    //            ProceeBillOrderCallHis(order.Id);
                    //        }).Start();

                    //}
                }
                else if (notificationInfo.BillOrderType == "IP")
                {
                    //支付状态：0未支付 1支付中 2支付成功 3支付失败 4退款中 5退款成功 6退款失败 7缴费中 8缴费成功 9缴费失败 10窗口退款成功
                    var order = ctx.InpatientPrepayOrders.FirstOrDefault(x => x.OrderNo == notificationInfo.BillOrderNo);
                    if (order != null) responseInfo = order.OrderStatus.ToString();
                }

            }

            return responseInfo;
        }


        private void CommonNotice(NotificationRequest notification)
        {
            var commonNotice = JsonConvert.DeserializeObject<CommonNotice>(notification.NotificationInfo);


            switch (commonNotice.NoticeType)
            {

                case 0: //缴费通知
                {
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                        var paperQuery =
                            ctx.SIWaitInvestigatePapers.FirstOrDefault(x => x.ClinicNo == commonNotice.ClinicNo);
                        if (paperQuery == null)
                        {
                            var paper = new SIWaitInvestigatePaper();
                            paper.Name = commonNotice.Name;
                            paper.CardNo = commonNotice.CardNo;
                            paper.CardType = 0;
                            paper.PatientId = commonNotice.PatientId;
                            paper.ClinicNo = commonNotice.ClinicNo;
                            paper.Type = 0;
                            paper.CreateTime = DateTime.Now;
                            paper.Status = 0;
                            paper.SubmitCount = 0;
                            var now = DateTime.Now;
                            if (now.Hour >= 6 && now.Hour < 18)
                            {
                                //白天的诊疗
                                paper.NeedSendTime = now.Date.AddHours(18).AddMinutes(now.Minute);
                            }
                            else
                            {
                                //晚上的诊疗
                                if (now.Hour > 6)
                                {
                                    paper.NeedSendTime = now.Date.AddDays(1).AddHours(10).AddMinutes(now.Minute);
                                }
                                else
                                {
                                    paper.NeedSendTime = now.Date.AddHours(10).AddMinutes(now.Minute);
                                }
                            }
                            paper.IsSended = 0;
                            ctx.SIWaitInvestigatePapers.Add(paper);
                            ctx.SaveChanges();
                        }

                            var wxUsers = ctx.HospCards.Where(x =>
                                x.PatientId == commonNotice.PatientId && x.DeleteStatus == 0 &&
                                x.CardStatus == 1);

                        foreach (var hospCard in wxUsers)
                        {

                            try
                            {
                                MessageHelper.SendNewBillMsg(hospCard.CardId);
                            }
                            catch (Exception ex)
                            {
                                Logger.ErrorFormat("发送缴费通知出错，信息:{0}", JsonConvert.SerializeObject(ex));
                            }
                        }
                    }
                }
                    break;
                case 1: //检验单通知
                {
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                            var wxUsers =
                                ctx.HospCards.Where(
                                    x => x.PatientId == commonNotice.PatientId && x.DeleteStatus == 0 && x.CardStatus == 1);

                        foreach (var hospCard in wxUsers)
                        {

                            try
                            {
                                MessageHelper.SendNewInspectionMsg(hospCard.CardId);
                            }
                            catch (Exception ex)
                            {
                                Logger.ErrorFormat("发送检验单通知出错，信息:{0}", JsonConvert.SerializeObject(ex));
                            }
                        }
                    }
                }
                    break;
                case 2: //检查单通知
                {
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                            var wxUsers =
                                ctx.HospCards.Where(
                                    x => x.PatientId == commonNotice.PatientId && x.DeleteStatus == 0 && x.CardStatus == 1);

                            foreach (var hospCard in wxUsers)
                        {

                            try
                            {
                                MessageHelper.SendNewCheckMsg(hospCard.CardId);
                            }
                            catch (Exception ex)
                            {
                                    Logger.ErrorFormat("检查单通知发送时出错，信息:{0}", JsonConvert.SerializeObject(ex));
                            }
                        }
                    }
                }
                    break;
            }
        }

        private bool HaltNotice(NotificationRequest notification)
        {
            var haltInfo = JsonConvert.DeserializeObject<HaltInfo>(notification.NotificationInfo);

            var haltDate = DateTime.Now;
            if (!DateTime.TryParse(haltInfo.HaltDate, out haltDate))
            {
                return true;
            }

            if (haltDate < DateTime.Now.Date)
            {
                return true;
            }

            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                var appoints =
                    ctx.ApptOrders.Where(
                        x =>
                            x.DeptId == haltInfo.DeptId && x.DoctorId == haltInfo.DoctorId &&
                            x.RegType == haltInfo.RegType && x.TimeSlice == haltInfo.TimeSlice &&x.RegDate==haltInfo.HaltDate && x.OrderStatus==21);
                

                foreach (var apptOrder in appoints)
                {
                    int cardType = apptOrder.CardType.ToInt32OrDefault(0);
                    var wxUsers = from hospCard in ctx.HospCards
                                  join wxUser in ctx.WxUsers on hospCard.WxUserId equals wxUser.Id
                                  //into temp from tt in temp.DefaultIfEmpty()
                                  where hospCard.CardNo == apptOrder.CardNo && hospCard.CardType == cardType && hospCard.DeleteStatus == 0 && hospCard.CardStatus == 1
                                  select new
                                  {
                                      OpenId = wxUser.OpenId,
                                      CardNo = hospCard.CardNo,
                                      CardType = hospCard.CardType,
                                      PatientName = hospCard.PatientName
                                  };
                    foreach (var hospCard in wxUsers)
                    {
                        string url = MessageHelper.GetH5Url("/index/reg-order-detail/" + apptOrder.Id);
                        var content =
                            string.Format(
                                "停诊通知\r姓名：{0}\r卡号：{1}\r科室：{2}\r医生：{3}\r就诊日期：{4}\r就诊时间：{5}\r已经停诊，请你退号后，尽快预约其他医生\r\n<a href='{6}'>点这里【退号】</a>",
                                hospCard.PatientName, hospCard.CardNo, apptOrder.DeptName, apptOrder.DoctorName,
                                apptOrder.RegDate,
                                apptOrder.OrderType == "2"
                                    ? apptOrder.StartTime + "-" + apptOrder.EndTime
                                    : apptOrder.StartTime, url);

                        try
                        {
                            MessageHelper.SendHaltMsg(hospCard.OpenId, content);
                        }
                       catch (Exception ex)
                       {
                            Logger.ErrorFormat("发送停诊通知出错，信息:{0}", JsonConvert.SerializeObject(ex));
                        }
                    }
                    apptOrder.HaltState = "1";
                    apptOrder.CancelByHospTime = haltInfo.ToDateTimeOrDefault(DateTime.Now);
                    ctx.SaveChanges();
                }
            }
            return true;
        }

        private void RefundNotice(NotificationRequest notification)
        {
            var refundInfo = JsonConvert.DeserializeObject<RefundInfo>(notification.NotificationInfo);

            var content = string.Format("");
            switch (refundInfo.RefundType)
            {
                case 0:
                    //退挂号费通知
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                        var appointOrder = ctx.ApptOrders.FirstOrDefault(x => x.OrderNo == refundInfo.OrderId);
                        if (appointOrder != null)
                        {
                            if (appointOrder.OrderStatusOnSetCheck == null && appointOrder.NextCheckTime == null)
                            {
                                if (appointOrder.PayState != "3")
                                {
                                    //收到退款通知，原订单状态不为已退款的，均认为是窗口退款28
                                    appointOrder.PayState = "3";
                                    appointOrder.OrderStatus = 28;
                                    appointOrder.RefundReason = appointOrder.RefundReason + "|退款通知确认退款";
                                    appointOrder.RefundTime = refundInfo.RefundTime;
                                    ctx.SaveChanges();
                                }
                            }
                        }
                    }
                    break;
                case 1:
                    //退处方费（(包括药费，检查/检验费)通知
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                        var billOrder = ctx.BillOrders.FirstOrDefault(x => x.ClinicNo == refundInfo.ClinicNo);
                        if (billOrder != null)
                        {
                            //在微信上缴费
                            if (billOrder.PayState != "3")
                            {
                                //收到退款通知，原订单状态不为已退款的，均认为是10窗口退款成功
                                billOrder.PayState = "3";
                                billOrder.OrderStatus = 10;
                                billOrder.RefundTime = refundInfo.RefundTime;
                                billOrder.Remark = billOrder.Remark + "|退款通知：确认退款";
                                ctx.SaveChanges();
                            }
                        }
                    }
                    break;
            }

        }

        //private void InpatientNotice(NotificationRequest notification)
        //{
        //    var notice = JsonConvert.DeserializeObject<InPatientNotice>(notification.NotificationInfo);

        //    using (var ctx = new GdsfybjyWeiXinEntities())
        //    {
        //        var wxUsers = ctx.HospCards.Where(x =>
        //            x.PatientId == notice.PatientId && x.DeleteStatus == 0 &&
        //            x.CardStatus == 1);


        //        foreach (var hospCard in wxUsers)
        //        {
        //            try
        //            {
        //                MessageHelper.SendInpatientMsg(hospCard.CardId);
        //            }
        //            catch (Exception ex)
        //            {
        //                Logger.ErrorFormat("发送入院缴费通知时出错，信息:{0}", JsonConvert.SerializeObject(ex));
        //            }
        //        }
        //    }
        //}

        /// <summary>
        /// 住院每日费用通知，新版可以在界面直接查询，故不需要这个方法
        /// </summary>
        /// <param name="notification"></param>
        //private void InpatientBillNotice(NotificationRequest notification)
        //{
            //var notice = JsonConvert.DeserializeObject<InPatientBillNotice>(notification.NotificationInfo);

            //using (var ctx = new GdsfybjyWeiXinEntities())
            //{
            //    var wxUsers = ctx.HospCards.Where(x =>
            //        x.PatientId == notice.PatientId && x.DeleteStatus == 0 &&
            //        x.CardStatus == 1);

            //    foreach (var hospCard in wxUsers)
            //    {
            //        //DateTime opDate;
            //        //if (!ctx.UserNotifications.Any(x => x.CardNo == hospCard.CardNo && x.OpenId == hospCard.OpenId
            //        //     && SqlFunctions.DateDiff("DAY", x.CreateTime, DateTime.Now) == 0))
            //        //{
            //            //DateTime.TryParse(notice.OPDate, out opDate);

            //            //var url = CustomSend.GetRedirectUrl("WxInpatient", "InpatientBillList?cardNo=" +
            //            //    hospCard.CardNo + "&cardType=" + hospCard.CardType + "&patientId=" + notice.PatientId +
            //            //    "&visitId=" + notice.VisitId + "&beginDate=" + opDate.AddDays(-1).ToString("yyyy-MM-dd") + "&endDate=" + opDate.ToString("yyyy-MM-dd"), hospCard.OpenId);

            //            //var content = string.Format("住院每日费用通知\r姓名：{0}\r卡号：{1}\r费用日期：{2}\r\n<a href='{3}'>点这里【查询住院每日费用】</a>",
            //            //    hospCard.Name, hospCard.CardNo, opDate.AddDays(-1).ToString("yyyy-MM-dd"), url);

            //            //var userNotification = new UserNotification();
            //            //userNotification.OpenId = hospCard.OpenId;
            //            //userNotification.Name = hospCard.Name;
            //            //userNotification.CardNo = notice.CardNo;
            //            //userNotification.CardType = notice.CardType;
            //            //userNotification.PatientId = notice.PatientId;
            //            //userNotification.CreateTime = DateTime.Now;
            //            //userNotification.Status = 0;
            //            //userNotification.Content = content;
            //            //userNotification.CreateTime = DateTime.Now;
            //            //userNotification.NeedSendTime = DateTime.Now.Date.AddHours(8).AddSeconds(DateTime.Now.Second);
            //            //userNotification.IsSended = 0;
            //            //ctx.UserNotifications.Add(userNotification);
            //       // }
            //    //}
            //    ctx.SaveChanges();
            //}
        //}

        private void SavePayNotifyLog(string tradeStatus, string outTradeNo, string gmt_payment, string trade_no, string openId, decimal total_fee)
        {
            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                //记录通知日志
                var orderNotifyLog = new WxPayNotifyLog
                {
                    ServiceVersion = "2.0",
                    Attach = "",
                    BankBillNo = "",
                    BankType = "AliPay",
                    BuyerAlias = "",
                    Discount = 0,
                    FeeType = 1,
                    InputCharset = "utf-8",
                    NotifyId = "",
                    SignType = "RSA",
                    Sign = "", //Request.Form["sign"],
                    SignKeyIndex = 0,
                    TradeMode = 1,
                    PayInfo = "",
                    TotalFee = (total_fee * 100).ToNullableInt32(),
                    TransactionId = trade_no,
                    OutTradeNo = outTradeNo,
                    TransportFee = 0,
                    ProductFee = (total_fee * 100).ToNullableInt32(),
                    PostAppId = "",
                    PostTimeStamp = gmt_payment,
                    PostNonceStr = "",
                    PostOpenId = "",
                    PostAppSignature = tradeStatus,
                    PostIsSubscribe = "1",
                    RecCreateDt = DateTime.Now,
                    TradeState = (tradeStatus == "TRADE_FINISHED" || tradeStatus == "TRADE_SUCCESS") ? 1 : 0
                };

                ctx.WxPayNotifyLogs.Add(orderNotifyLog);
                ctx.SaveChanges();
            }
        }

        private void ProccessFaceToFacePaidOrder(string outTradeNo, string gmt_payment, string trade_no,string openId,decimal total_fee)
        {
            try
            {
                long wxUserId = 0;
                using (var ctx = new GdsfybjyWeiXinEntities())
                {
                    var wxUser = ctx.WxUsers.FirstOrDefault(x => x.OpenId == openId);
                    if (wxUser == null)
                    {
                        var newWxUser = new WxUser
                        {
                            OpenId = openId,
                            LastActiveDt = DateTime.Now,
                            IsBkMember = 0,
                            BkMemberId = null,
                            RecStatus = 1,
                            RecCreateDt = DateTime.Now,
                            UserType = "AliPay"
                        };

                        ctx.WxUsers.Add(newWxUser);
                        ctx.SaveChanges();
                        wxUserId = newWxUser.Id;
                    }
                    else
                    {
                        wxUserId = wxUser.Id;
                    }
                }
                if (outTradeNo.StartsWith("BL"))
                {
                    //缴费单 执行缴费操作
                    var orderNo = outTradeNo.Substring(2);
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                        var order = ctx.BillOrders.FirstOrDefault(x => x.OrderNo == orderNo);

                        if (order != null)
                        {
                            if (order.OrderStatus == BillOrderExtensions.OrderStatus.未支付.ToInt32())
                            {
                                var patient = ctx.HospCards.FirstOrDefault(x => x.CardNo == order.CardNo);
                                order.CardName = patient?.PatientName;
                                order.PayState = BillOrderExtensions.PayState.已付款.ToInt32().ToString();
                                order.OrderStatus = BillOrderExtensions.OrderStatus.支付成功.ToInt32();
                                //更新订单类型
                                order.AliPayType = "BARCODEPAYOFFLINE";
                                order.PayTime = DateTime.Parse(gmt_payment);
                                order.WxTransactionId = trade_no;
                                order.WxUserId = wxUserId;
                                ctx.SaveChanges();

                                // RMQ 执行缴费操作
                                var pickupingProducer = new OrderPickupingProducer();
                                pickupingProducer.Publish(new OrderPickupingMsg
                                {
                                    OrderType = Rmq.Center.OrderType.门诊缴费订单,
                                    OrderId = order.Id
                                });
                            }
                            //如果订单状态为支付失败（订单15分钟已关闭，用户），或者His缴费失败 added by wesley
                            else if (order.OrderStatus == BillOrderExtensions.OrderStatus.缴费失败.ToInt32() ||
                                     order.OrderStatus == BillOrderExtensions.OrderStatus.支付失败.ToInt32())
                            {
                                //执行退款操作
                                var refundingProducer = new OrderRefundingPickupFailedProducer();
                                refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                                {
                                    OrderType = OrderType.门诊缴费订单,
                                    OrderId = order.Id
                                });
                            }
                        }
                        else
                        {
                            AlipayNotifyHelper.AcquireRefund(trade_no, outTradeNo, total_fee, openId);
                        }
                    }
                }
                else if (outTradeNo.StartsWith("IP"))
                {
                    #region 住院充值支付成功通知

                    //缴费单 执行缴费操作
                    var orderNo = outTradeNo.Substring(2);
                    InpatientPrepayOrder order;
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                        order = ctx.InpatientPrepayOrders.FirstOrDefault(x => x.OrderNo == orderNo);
                        if (order != null)
                        {
                            if (order.OrderStatus == PrepayOrderExtensions.OrderStatus.未支付.ToInt32())
                            {
                                var patient = ctx.HospCards.FirstOrDefault(x => x.CardNo == order.CardNo);
                                order.CardName = patient?.PatientName;
                                order.PayState = PrepayOrderExtensions.PayState.已付款.ToInt32().ToString();
                                order.OrderStatus = PrepayOrderExtensions.OrderStatus.支付成功.ToInt32();
                                //更新订单类型
                                order.AliPayType = "BARCODEPAYOFFLINE";
                                order.PayTime = DateTime.Parse(gmt_payment);
                                order.WxTransactionId = trade_no;
                                order.OpenId = openId;
                                ctx.SaveChanges();

                                // RMQ 执行缴纳预缴金操作
                                var pickupingProducer = new OrderPickupingProducer();
                                pickupingProducer.Publish(new OrderPickupingMsg
                                {
                                    OrderType = Rmq.Center.OrderType.住院预缴金订单,
                                    OrderId = order.Id
                                });
                            }
                            else if (order.OrderStatus == PrepayOrderExtensions.OrderStatus.缴费失败.ToInt32())
                            {
                                //His缴费失败，执行退款操作
                                var refundingProducer = new OrderRefundingPickupFailedProducer();
                                refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                                {
                                    OrderType = OrderType.住院预缴金订单,
                                    OrderId = order.Id
                                });
                            }

                        }
                        else
                        {
                            AlipayNotifyHelper.AcquireRefund(trade_no, outTradeNo, total_fee, openId);
                        }
                    }

                    #endregion
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用当面付处理订单ProccessFaceToFacePaidOrder出错，信息:{0}", JsonConvert.SerializeObject(ex));
            }

        }
    }
}
